﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using LetiLib.Security;
using LetiLib.Connection;
using LetiLib.Data;

namespace LetiLib.Device
{
    class Sender
    {
        /// <summary>
        /// Send Ping command to device
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool vSendPingCmd(Socket socket)
        {
            // Create buffer
            byte[] btSend = new byte[2];

            btSend[0] = (byte)COMMAND.SERVER_TAG;
            btSend[1] = (byte)COMMAND.PING;

            // send buffer data
            return SendBytes(socket, btSend);
        }

        /// <summary>
        /// Get current device version
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool vSendGetVersionCmd(Socket socket)
        {
            byte[] btSend = new byte[2];
            btSend[0] = (byte)COMMAND.SERVER_TAG;
            btSend[1] = (byte)COMMAND.GET_VERSION;

            // send buffer data
            return SendBytes(socket, btSend);
        }

        // CMDs sent to Mobiles
        public static bool vSendGetPassCmd(Socket socket)
        {
            // create buffer
            byte[] btSend = new byte[2];
            btSend[0] = (byte)COMMAND.SERVER_TAG;
            btSend[1] = (byte)COMMAND.GET_PASSWORD;

            // send buffer data
            return SendBytes(socket, btSend);
        }

        // Update data commands
        public static bool vSendUpdatePlaylistRequest(Socket socket)
        {
            // create buffer
            byte[] data = new byte[2];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_SERVER_PLAYLIST_UPDATE_REQ;
            
            // send buffer data
            return SendBytes(socket, data);
        }
        public static bool vSendPlaylistInfo(Socket socket, PlaylistInfo plInfo)
        {
            // send buffer data
            return SendBytes(socket,plInfo.Data);
            
        }

        // Update [redefined commands
        public static bool vSendUpdatePredefinedRequest(Socket socket, ushort order,ushort index)
        {
            byte[] data = new byte[6];
            data[0] = (byte)COMMAND.SERVER_TAG;
            //data[1] = (byte)COMMAND.CMD_SERVER_PREDEFINED_UPDATE_REQ;
            BitConverter.GetBytes(order).CopyTo(data, 2);
            BitConverter.GetBytes(index).CopyTo(data, 4);
            // send buffer data
            return SendBytes(socket, data);
        }

        // Update data commands
        public static bool vSendUpdateDataRequest(Socket socket, Int16 version)
        {
            byte[] data = new byte[2];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_SERVER_DATA_UPDATE_REQ;
            
            // send buffer data
            return SendBytes(socket, data);
        }

        public static bool vSendUpdateDataInfo(Socket socket, DataInfo dataInfo)
        {
            // send buffer data
            return SendBytes(socket,dataInfo.Data);
        }

        static int iTmpData = 0;
        public static bool vSendUpdateDataPackage(Socket socket, DataPackage package)
        {
            iTmpData++;

            byte crc = CRC.ComputeChecksum(package.Data);
            byte[] outBuf = new byte[package.Data.Length + 1];
            Array.Copy(package.Data, 0, outBuf, 0, package.Data.Length);
            if (iTmpData % 10 == 0) crc++;
            outBuf[package.Data.Length] = crc;
            // send buffer data
            return SendBytes(socket, outBuf);

        }

        #region | Update firmware |
        /// <summary>
        /// Send update firmware request to device
        /// After this command, device will be waiting for firmware Info package
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool vSendUpdateFirmwareRequest(Socket socket)
        {
            byte[] data = new byte[2];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_SERVER_FIRMWARE_UPDATE_REQ;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send firmware info to device
        /// After this command, device will be waited for firmware package
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <param name="frmInfo">Firmware information header</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool vSendUpdateFirmwareInfo(Socket socket, FirmwareInfo frmInfo)
        {
            iTmp = 0;
            // send buffer data
            return SendBytes(socket, frmInfo.Data);
        }

        static int iTmp = 0;
        /// <summary>
        /// Send firmware package to device
        /// 
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <param name="package">firmware data package</param>
        /// <returns>Return true if success, error if there are any exceptions
        ///
        /// </returns>
        public static bool vSendUpdateFirmwarePackage(Socket socket, FirmwarePackage package)
        {
            iTmp++;

            byte crc = CRC.ComputeChecksum(package.Data);
            byte[] outBuf = new byte[package.Data.Length + 1];
            Array.Copy(package.Data, 0, outBuf, 0, package.Data.Length);
            if (iTmp % 10 == 0) crc++;
            outBuf[package.Data.Length] = crc;

            // send buffer data
            return SendBytes(socket, outBuf);
        }
        #endregion

        #region | Update font |
        /// <summary>
        /// Send update firmware request to device
        /// After this command, device will be waiting for firmware Info package
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool vSendUpdateFontRequest(Socket socket)
        {
            byte[] data = new byte[2];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_SERVER_FONT_UPDATE_REQ;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send firmware info to device
        /// After this command, device will be waited for firmware package
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <param name="frmInfo">Firmware information header</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool vSendUpdateFontInfo(Socket socket, FontInfo frmInfo)
        {
            iTmp = 0;
            // send buffer data
            return SendBytes(socket, frmInfo.Data);
        }

        /// <summary>
        /// Send firmware package to device
        /// 
        /// </summary>
        /// <param name="socket"> Device socket</param>
        /// <param name="package">firmware data package</param>
        /// <returns>Return true if success, error if there are any exceptions
        ///
        /// </returns>
        public static bool vSendUpdateFontPackage(Socket socket, FontPackage package)
        {
            iTmp++;

            byte crc = CRC.ComputeChecksum(package.Data);
            byte[] outBuf = new byte[package.Data.Length + 1];
            Array.Copy(package.Data, 0, outBuf, 0, package.Data.Length);
            if (iTmp % 10 == 0) crc++;
            outBuf[package.Data.Length] = crc;

            // send buffer data
            return SendBytes(socket, outBuf);
        }
        #endregion

        public static bool SendCreateBlankPageCmd(Socket socket,ushort mID)
        {            
            LETIPage pg = new LETIPage(mID);

            byte[] data = new byte[2 +pg.BufferSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_CREATE_PAGE;

            pg.getBytes().CopyTo(data, 2);

            // send buffer data
            return SendBytes(socket, data);
        }

#if BUSDATA_ENABLED
        /// <summary>
        /// This is functions for bus device.
        /// For testing.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="strContent"></param>
        /// <returns></returns>
        public static bool UpdateBusData(Socket socket,string strContent)
        {
            byte[] data = new byte[4 + strContent.Length];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_UPDATE_BUS_DATA;
            BitConverter.GetBytes((ushort)strContent.Length).CopyTo(data, 2);
            Encoding.ASCII.GetBytes(strContent).CopyTo(data, 4);

            // send buffer data
            return SendBytes(socket, data);
        }
#endif

        /// <summary>
        /// Change current background image.
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">current active page id</param>
        /// <param name="popupID">background popup id</param>
        /// <param name="playOrder">image playrorder</param>
        /// <param name="imgID">new image ID</param>
        /// <returns></returns>
        public static bool SendActiveImage(Socket socket, ushort pageID, ushort popupID, byte playOrder,ushort imgID)
        {
            byte[] data = new byte[12];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_UPDATE_IMAGE_TO_PLAYLIST;
            BitConverter.GetBytes((ushort)12).CopyTo(data, 2);
            BitConverter.GetBytes(pageID).CopyTo(data, 4);
            BitConverter.GetBytes(popupID).CopyTo(data, 6);
            BitConverter.GetBytes(playOrder).CopyTo(data, 8);
            BitConverter.GetBytes(imgID).CopyTo(data, 9);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Active one page in device
        /// </summary>
        /// <param name="socket">device socket</param>
        /// <param name="pageID"> page id to be actived</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendActivePage(Socket socket, ushort pageID)
        {
            byte[] data = new byte[4];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_SET_ACTIVE_PAGE;
            BitConverter.GetBytes(pageID).CopyTo(data, 2);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Create new page on device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="page">Page data</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendCreatePageCmd(Socket socket, LETIPage page)
        {
            byte[] data;
            if (page == null)
            {
                data = new byte[4];
                data[0] = (byte)COMMAND.SERVER_TAG;
                data[1] = (byte)COMMAND.CMD_CREATE_PAGE;
                BitConverter.GetBytes(0).CopyTo(data, 2);
            }
            else
            {
                data = new byte[4 + page.BufferSize];
                data[0] = (byte)COMMAND.SERVER_TAG;
                data[1] = (byte)COMMAND.CMD_CREATE_PAGE;
                BitConverter.GetBytes((ushort)page.BufferSize).CopyTo(data, 2);
                page.getBytes().CopyTo(data, 4);
            }
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Update existing page header
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page to be updated</param>
        /// <param name="pageHeader">Page header data</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendUpdatePageHeaderCmd(Socket socket, ushort pageID, LETIPageHeader pageHeader)
        {
            byte[] data;

            data = new byte[6 + LETIPage.PAGE_HEADER_SIZE];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_UPDATE_PAGE;
            BitConverter.GetBytes((ushort)data.Length).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)pageHeader.ID).CopyTo(data, 6);
            data[8] = (byte)pageHeader.ItemCount;
            data[9] = (byte)pageHeader.EventType;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Delete one page from device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page ID</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendDeletePage(Socket socket, ushort pageID)
        {
            byte[] data = new byte[4];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_DELETE_PAGE;
            BitConverter.GetBytes(pageID).CopyTo(data, 2);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Get current active page id from device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendGetActivePageCmd(Socket socket)
        {
            byte[] data = new byte[2];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_GET_ACTIVE_PAGE;
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Insert new popup to page
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page to be inserted</param>
        /// <param name="popupID">Popup index to be inserted to</param>
        /// <param name="popupData">Popup data</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendInsertPopupCmd(Socket socket, ushort pageID, ushort popupID, POPUP popupData)
        {
            byte[]tempBuf = popupData.getBytes();
            ushort bufSize = (ushort)(8 + tempBuf.Length);
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_INSERT_POPUP;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)popupID).CopyTo(data, 6);
            tempBuf.CopyTo(data, 8);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Update popup of page
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page containts popup</param>
        /// <param name="popupID">Popup index to be updated</param>
        /// <param name="popupData">Popup data</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendUpdatePopupCmd(Socket socket, ushort pageID, ushort popupID, POPUP popupData)
        {
            ushort bufSize = 0;
            
            bufSize = (ushort)(8 + popupData.getBytes().Length);
            
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_UPDATE_POPUP;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)popupID).CopyTo(data, 6);
            popupData.getBytes().CopyTo(data, 8);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Insert image to popup playlist 
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page containts popup</param>
        /// <param name="popupID">Popup index to be updated</param>
        /// <param name="imageData">Image code on device</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        internal static bool SendInsertImageToPlaylistCmd(Socket socket, ushort pageID, ushort popupID, IMAGE imageData)
        {
            ushort bufSize = (ushort)(8 + IMAGE.IMAGE_LENGTH);
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_INSERT_IMAGE_TO_PLAYLIST;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)popupID).CopyTo(data, 6);
            imageData.getBytes().CopyTo(data, 8);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Update image to popup playlist 
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page containts popup</param>
        /// <param name="popupID">Popup index to be updated</param>
        /// <param name="playOrder">Image index in playlist</param>
        /// <param name="imageData">Image code on device</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        internal static bool SendUpdateImageCmd(Socket socket, ushort pageID, ushort popupID, byte playOrder, IMAGE imageData)
        {
            ushort bufSize = (ushort)(9 + IMAGE.IMAGE_LENGTH);
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_UPDATE_IMAGE_TO_PLAYLIST;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)popupID).CopyTo(data, 6);
            BitConverter.GetBytes((byte)playOrder).CopyTo(data, 8);
            imageData.getBytes().CopyTo(data, 9);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Delete one image from popup playlist
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page containts popup playlist</param>
        /// <param name="popupID">popup id</param>
        /// <param name="playOrder">Image index in playlist</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        internal static bool SendDeleteImageFromPlaylistCmd(Socket socket, ushort pageID, ushort popupID, byte playOrder)
        {
            ushort bufSize = (ushort)(9);
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_DELETE_IMAGE_FROM_PLAYLIST;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)popupID).CopyTo(data, 6);
            data[8] = playOrder;
            //BitConverter.GetBytes((byte)playOrder).CopyTo(data, 8);

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Delete one popup on page
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page id</param>
        /// <param name="popupID">Popup id to be deleted</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendDeletePopupCmd(Socket socket, ushort pageID, ushort popupID)
        {
            ushort bufSize = (ushort)(8);
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_DELETE_POPUP;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            BitConverter.GetBytes((ushort)popupID).CopyTo(data, 6);
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Get information of one page on device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="pageID">Page ID</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendPageInfoCmd(Socket socket, ushort pageID)
        {
            ushort bufSize = 6;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_GET_PAGE_INFO;
            BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)pageID).CopyTo(data, 4);
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Delete image binary data on device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="imgageID">Image ID</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendDeleteImageCmd(Socket socket, ushort imgageID)
        {
            ushort bufSize = 4;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_DELETE_IMAGE;
            //BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            BitConverter.GetBytes((ushort)imgageID).CopyTo(data, 2);
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send image binary data from sd card on device to ROM
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <param name="imgageID">Image ID</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendSetPredefineCmd(Socket socket, ushort imgageID,byte romID)
        {
            ushort bufSize = 5;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_SET_PREDEFINE ;
            BitConverter.GetBytes((ushort)imgageID).CopyTo(data, 2);
            data[4] = romID;
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Delete all images binary data
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendDeleteAllImageCmd(Socket socket)
        {
            ushort bufSize = 2;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_DELETE_ALL_IMAGE;
            //BitConverter.GetBytes((ushort)bufSize).CopyTo(data, 2);
            //BitConverter.GetBytes((ushort)imgageID).CopyTo(data, 2);
            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Get available image on device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns>Return true if success, error if there are any exceptions</returns>
        public static bool SendGetImageListCmd(Socket socket)
        {
            ushort bufSize = 2;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_GET_LIST_IMAGE_INDEX;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send check led status command to device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns></returns>
        public static bool SendCheckLedCmd(Socket socket)
        {
            ushort bufSize = 2;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_CHECK_LED;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send check led status command to device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns></returns>
        public static bool SendGetStatusCmd(Socket socket)
        {
            ushort bufSize = 2;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_GET_STATUS;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send capture screen command to device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns></returns>
        public static bool SendScreenCaptureCmd(Socket socket)
        {
            ushort bufSize = 2;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_CAPTURE_SCREEN;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send reboot command to device
        /// </summary>
        /// <param name="socket">Device socket</param>
        /// <returns></returns>
        public static bool SendRebootCmd(Socket socket)
        {
            ushort bufSize = 2;
            byte[] data = new byte[bufSize];
            data[0] = (byte)COMMAND.SERVER_TAG;
            data[1] = (byte)COMMAND.CMD_REBOOT;

            // send buffer data
            return SendBytes(socket, data);
        }

        /// <summary>
        /// Send byte array data to device
        /// </summary>
        /// <param name="socket">Device's socket</param>
        /// <param name="bytes">Data byte array</param>
        /// <param name="nTry">This will try nTry times if send error</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException" />
        /// <exception cref="SocketException" />
        /// <exception cref="ObjectDisposedException" />
        public static bool SendBytes(Socket socket,byte[] bytes,ushort nTry = 3)
        {
            if (socket == null) return false;

            // XOR cypher
            for (int i = 0; i < bytes.Length;i++ )
                bytes[i] ^= 0xAB;

            int byteSents = 0;
            int temp = nTry;
            while (byteSents != bytes.Length)
            {
                if (temp <= 0)
                    break;
                //socket.Accept//
                
                try
                {
                    byteSents = socket.Send(bytes);
                }
                catch (System.Exception ex)
                {
                    byteSents = 0;
                }
                
                temp--;
            }

            if (temp <= 0)
                return false;
            else return true;
        }

        
    }
}
